﻿using Sys.Core.Models.Dto;
using Sys.Core.Models.VO;
using Sys.Core.Providers;
using MiniFox;
using MiniFox.Components;
using MiniFox.Infrastructure;
using MiniFox.Platform.Applications;
using MiniFox.Platform.Applications.Auth;

namespace Sys.Core.Services
{
    public class MenuService : ApiServiceBase, IMenuService
    {
        public MenuService(SystemPrincipal principal) : base(principal)
        {
        }

        [AutoWired]
        public IMenuProvider Provider { get; set; }

        public IEnumerable<ITreeNode> Query()
        {
            var menuItems = this.Provider.GetMenuItems();
            TreeResultObject<MenuVo> treeResult = new TreeResultObject<MenuVo>(menuItems);
            return treeResult.Result;
        }
        protected void CreateMenuPath(MenuDto menu)
        {
            var parent = this.Provider.GetMenuItem(menu.ApplicationID, menu.ParentMenuID);
            var menuPath = $"{parent.MenuPath}/{menu.MenuName.Trim()}";
            menu.MenuPath = menuPath;
        }
        protected void CheckMenuPath(string menuPath)
        {
            if (this.Provider.MenuExists(menuPath))
                throw new InvalidOperationException("菜单已存在");
        }

        public MenuVo Create(MenuDto menu)
        {
            menu.MenuID = SequenceGUID.NewGUID();
            this.CreateMenuPath(menu);
            this.CheckMenuPath(menu.MenuPath);
            return this.Provider.CreateMenuItem(menu) ? this.Provider.GetMenuItem(menu.MenuPath) : null;
        }

        public MenuVo Update(MenuDto menu)
        {
            this.CreateMenuPath(menu);
            return this.Provider.UpdateMenuItem(menu) ? this.Provider.GetMenuItem(menu.MenuPath) : null;
        }

        public string Delete(string appId, string menuId)
        {
            var menu = this.Provider.GetMenuItem(appId, menuId);
            var menuPath = menu.MenuPath;

            return this.Provider.DeleteMenuItem(menuPath) ? menuPath : null;
        }

        public string Delete(string menuPath)
        {
            return this.Provider.DeleteMenuItem(menuPath) ? menuPath : null;
        }

        public IEnumerable<MenuModuleVo> GetMenuModules(string appId, string menuId)
        {
            return this.Provider.GetMenuModules(appId, menuId);
        }

        public IEnumerable<MenuModuleVo> AddMenuModules(MenuModuleSet menuModuleSet)
        {
            this.Provider.CreateMenuModules(menuModuleSet.ApplicationID, menuModuleSet.MenuID, menuModuleSet.Modules);
            return this.Provider.GetMenuModules(menuModuleSet.ApplicationID, menuModuleSet.MenuID);
        }

        public IEnumerable<MenuModuleVo> RemoveMenuModules(MenuModuleSet menuModuleSet)
        {
            this.Provider.DeleteMenuModules(menuModuleSet.ApplicationID, menuModuleSet.MenuID, menuModuleSet.Modules);
            return this.Provider.GetMenuModules(menuModuleSet.ApplicationID, menuModuleSet.MenuID);
        }

        public IEnumerable<MenuModuleVo> EditMenuModule(MenuModuleDto menuModule)
        {
            this.Provider.UpdateMenuModule(menuModule);
            return this.Provider.GetMenuModules(menuModule.ApplicationID, menuModule.MenuID);
        }

        public IEnumerable<MenuLinkVo> GetMenuLinks(string appId, string menuId)
        {
            return this.Provider.GetMenuLinks(appId, menuId);
        }

        public MenuLinkVo CreateLink(MenuLinkDto link)
        {
            link.LinkID = SequenceGUID.NewGUID();
            bool success = this.Provider.CreateMenuLink(link);
            return success ? this.Provider.GetMenuLink(link.LinkID) : null;
        }

        public MenuLinkVo UpdateLink(MenuLinkDto link)
        {
            bool success = this.Provider.UpdateMenuLink(link);
            return success ? this.Provider.GetMenuLink(link.LinkID) : null;
        }

        public string DeleteLink(string linkId)
        {
            bool success = this.Provider.DeleteMenuLink(linkId);
            return success ? linkId : null;
        }

    }
}